package com.attrisoft.sanger.aws;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import com.amazonaws.auth.PropertiesCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.GetObjectRequest;
import com.amazonaws.services.s3.model.ListObjectsRequest;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.ObjectListing;
import com.amazonaws.services.s3.model.S3ObjectSummary;

public class S3Client {
    
    private static String bucket = System.getProperty("AwsBucket");
    private static String credentials = System.getProperty("AwsCredentials");
    
    public static void upload(String folder, String path, String fname) throws IOException {
        AmazonS3 s3 = new AmazonS3Client(new PropertiesCredentials(new File(credentials)));
        s3.putObject(new PutObjectRequest(bucket, folder +"/" +fname, new File(path + java.io.File.separator +fname)));
    }
    
    public static List<String> getWorkflows(String folder) throws IOException {
        AmazonS3 s3 = new AmazonS3Client(new PropertiesCredentials(new File(credentials)));
        ObjectListing objectListing = s3.listObjects(new ListObjectsRequest().withBucketName(bucket).withPrefix(folder));
        List<String> workflows = new ArrayList<String>();
        for (S3ObjectSummary os : objectListing.getObjectSummaries()) {
            String name = os.getKey().substring(folder.length()+1);
            if (name.indexOf('/') > 0) {
                name = name.substring(0, name.indexOf('/'));
                if (!workflows.contains(name)) 
                    workflows.add(name);
            }
        }
        return workflows;
    }
        
    public static List<FileInfo> getInput(String user, String workflow) throws IOException {
        return getFiles(user +"/" +workflow +"/input");
    }
    
    public static List<FileInfo> getOutput(String user, String workflow) throws IOException {
        return getFiles(user +"/" +workflow +"/output");
    }
    
    private static List<FileInfo> getFiles(String folder) throws IOException {
        AmazonS3 s3 = new AmazonS3Client(new PropertiesCredentials(new File(credentials)));
        ObjectListing objectListing = s3.listObjects(new ListObjectsRequest().withBucketName(bucket).withPrefix(folder));
        ArrayList<FileInfo> list = new ArrayList<FileInfo>();
        for (S3ObjectSummary os : objectListing.getObjectSummaries()) {
            if (os.getSize() > 0) {
                list.add(new FileInfo(os.getKey().substring(folder.length()+1), os.getSize(), os.getLastModified()));
            }
        }
        return list;
    }
    
    public static void deleteWorkflow(String user, String workflow) throws IOException {
        AmazonS3 s3 = new AmazonS3Client(new PropertiesCredentials(new File(credentials)));
        ObjectListing objectListing = s3.listObjects(
            new ListObjectsRequest().withBucketName(bucket).withPrefix(user +"/" +workflow));
        for (S3ObjectSummary os : objectListing.getObjectSummaries()) {
            s3.deleteObject(bucket, os.getKey());
        }       
    }
    
    public static void createWorkflow(String user, String name, File[] input, File[] output) throws IOException {
        AmazonS3 s3 = new AmazonS3Client(new PropertiesCredentials(new File(credentials)));
        for (File in : input) {
            if (in.length() < 200 * 1024)
                s3.putObject(new PutObjectRequest(bucket, user +"/" +name +"/input/" +in.getName(), in));
            else 
                System.err.println("##### Skipping: " +in.getName());
        }
        for (File out : output) 
            s3.putObject(new PutObjectRequest(bucket, user +"/" +name +"/output/" +out.getName(), out));
    }
    
    public static InputStream get(String folder, String fname) throws IOException {
        AmazonS3 s3 = new AmazonS3Client(new PropertiesCredentials(new File(credentials)));
        S3Object object = s3.getObject(new GetObjectRequest(bucket, folder +"/" +fname)); 
        return object.getObjectContent();
    }
    
    public static boolean workflowExists(String user, String name) {
        try {
            return getWorkflows(user).contains(name);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }
}
